package sky.dao.Impl;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import sky.dao.AbstractDAO;
import sky.domain.ModelObject;
import sky.tro.finders.AbstractFinder;

import java.sql.SQLException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Gauss
 * Date: 19.10.13
 * Time: 13:26
 * To change this template use File | Settings | File Templates.
 */
@Repository
public abstract class AbstractDAOImpl<T extends ModelObject> implements AbstractDAO<T> {

    protected HibernateTemplate template;

    protected Class<T> domainClass = getDomainClass();

    protected abstract Class<T> getDomainClass();

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        template = new HibernateTemplate(sessionFactory);
    }

    @Override
    public void add(T t) {
        template.save(t);
    }

    @Override
    public void edit(T t) {
        template.update(t);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void remove(Integer id) {
        T t = template.load(domainClass, id);
        if (null != t) {
            template.delete(t);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<T> list() {
        return template.find("from " + domainClass.getName());
    }

    @Override
    public T getById(Integer id) {
        return template.get(domainClass, id);
    }

    @Override
    @SuppressWarnings({"unchecked", "JpaQlInspection"})
    public T getByName(String name, Boolean isInitialize) {
        T t = (T) template.find("from " + domainClass.getName() + " where name = ?", name).iterator().next();
        if (isInitialize) {
            t.initialize();
        }
        return t;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<T> listByFinder(final AbstractFinder abstractFinder) {
        return template.execute(new HibernateCallback<List<T>>() {
            @Override
            public List<T> doInHibernate(Session session) throws HibernateException, SQLException {
                return abstractFinder.fillCriteria(session.createCriteria(domainClass)).list();
            }
        });
    }
}
